package org.goldfish.chatroom.service.impl;

import jakarta.mail.internet.*;
import jakarta.mail.*;
import org.apache.logging.log4j.Logger;
import org.goldfish.chatroom.entity.VerificationMessage;
import org.goldfish.chatroom.intercepter.LogInterceptor;
import org.goldfish.chatroom.service.MailVerificationServiceManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import static jakarta.mail.Message.RecipientType.TO;

@Service
public class MailVerificationServiceManagerImpl implements MailVerificationServiceManager {

    @Autowired
    TemplateEngine templateEngine;

    private final String SENDER_MAIL_ADDRESS;
    private final String ADMIN_MAIL_ADDRESS;
    private final String AUTHORIZATION_CODE; // Replace with your actual authorization code

    private final String PROPERTY_FILE_NAME = "mail_verify.properties";
    private final Properties properties;
    /**
     * global variable indicating where this is used in a debug environment<br/>
     * true only when specified in file mail_verify.properties
     */
    private final boolean debug;
    private final String debug_ip;

    private static final Logger logger = org.apache.logging.log4j.LogManager.getLogger(LogInterceptor.class);


    public MailVerificationServiceManagerImpl() throws IOException {
        properties = new Properties();
        try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(PROPERTY_FILE_NAME)) {
            if (inputStream == null) {
                throw new FileNotFoundException("Property file '" + PROPERTY_FILE_NAME + "' not found in the classpath");
            }
            properties.load(inputStream);
            logger.atDebug().log("Loaded properties from file '" + PROPERTY_FILE_NAME + "'");
            logger.atDebug().log(properties.toString());
        }
        SENDER_MAIL_ADDRESS = Objects.requireNonNull(properties.getProperty("goldfish.mail.from"));
        ADMIN_MAIL_ADDRESS = Objects.requireNonNull(properties.getProperty("goldfish.mail.to"));
        AUTHORIZATION_CODE = Objects.requireNonNull(properties.getProperty("goldfish.smtp.code"));
        debug = Boolean.parseBoolean(properties.getProperty("goldfish.debug"));
        debug_ip = properties.getProperty("goldfish.debug.ip");
    }

    @Override
    public void sendVerificationMessage(VerificationMessage verificationMessage) {
        Session session = Session.getInstance(properties,
                new jakarta.mail.Authenticator() {
                    @Override
                    protected jakarta.mail.PasswordAuthentication getPasswordAuthentication() {
                        return new jakarta.mail.PasswordAuthentication(SENDER_MAIL_ADDRESS, AUTHORIZATION_CODE);
                    }
                });

        try {
            MimeMessage message = new MimeMessage(session);
            message.setFrom(new InternetAddress(SENDER_MAIL_ADDRESS));
            message.setRecipient(TO, new InternetAddress(ADMIN_MAIL_ADDRESS));
            message.setSubject("Verification Message");
            Context context = new Context();
            context.setVariable("serial_value", verificationMessage.getSerialNumber());
            context.setVariable("quick_link", quickLink(verificationMessage));
            String content = templateEngine.process("mail", context);

            message.setContent(content, "text/html");
            Transport.send(message);
        } catch (MessagingException e) {
            e.printStackTrace();
        }
    }

    @Override
    public String getReceiveAddress() {
        return (ADMIN_MAIL_ADDRESS);
    }

    /**
     * map helping translate foo@qq.com to mail.qq.com
     *
     * @return a map
     */
    private Map<String, String> mailProviderMap = initMailServiceProviderMap();

    private Map<String, String> initMailServiceProviderMap() {
        Map<String, String> map = new HashMap<>();
        map.put("qq.com", "mail.qq.com");
        return map;
    }

    public String translate(String content) {
        String[] provider_raw = content.split("@");
        if (provider_raw.length == 0)
            return content;
        String[] s = {provider_raw[provider_raw.length - 1]};
        mailProviderMap.forEach(
                (k, v) -> {
                    if (s[0].contains(k))
                        s[0] = s[0].replace(k, v);
                }
        );
        return "https://" + s[0];
    }

    private String quickLink(VerificationMessage message) {
        return String.format(Locale.CHINA, "%s?autofill=%s",
                debug ? properties.getProperty("goldfish.debug.ip") : properties.getProperty("goldfish.release.domain"),
                message.getSerialNumber()
        );
    }
}